import {makeAutoObservable,makeObservable,observable,computed,action,flow,runInAction,flowResult,autorun,reaction,when,toJS} from "mobx";

class MakeObservableStore {
    value = 0;
    constructor(){
        makeObservable(this,{
            value:observable
        })
    }
    get double(){
        return this.value *2;
    }

    increment = () => {
        this.value++;
    }
}
export const makeObservableStore = new MakeObservableStore();


class MakeAutoObservableStore {
    count = 0;
    constructor(){
        makeAutoObservable(this);
    }

    addCount = () => {
        this.count++;
    }
}
export const makeAutoObservableStore = new MakeAutoObservableStore();


class DecoratorStore {
    @observable count:number = 0;
    constructor(){
        makeObservable(this);
    }

    @action 
    increment = async () => {
        await new Promise((resolve) => {
            setTimeout(() => {
                this.count += 10;
                resolve(true);
            })

        })
    }
}
export const decoratorStore = new DecoratorStore();

class RunInactionStore {
    @observable count:number = 0;
    constructor(){
        makeObservable(this);
    }

    @action.bound
    increment(){
        return new Promise((resolve,reject) => {
            setTimeout(() => {
                resolve(200)
            },2000)
        }).then(res => {
            runInAction(() => {
                this.count = res as number;
            })
        })
    }
}
export const runInActionStore = new RunInactionStore();

class FlowStore {
    count = 0;
    constructor(){
        makeAutoObservable(this);
    }

    *increment () {
        this.count = yield new Promise(res => setTimeout(() => res(1),1000));
        this.count = yield new Promise(res => setTimeout(() => res(2),2000));
    }
}
export const flowStore = new FlowStore();


class ComputedStore {
    @observable count:number = 0;
    constructor(){
        makeObservable(this);
    }

    get doubleCount(){
        return this.count * 2;
    }

    @action.bound
    increment(){
        this.count += 1;
    }
}
export const computedStore = new ComputedStore();

class AutoRunStore {
    @observable count:number = 0;
    @observable change_log:string[] = [];

    constructor(){
        makeObservable(this);
    }

    @action.bound
    increment(){
        this.count ++;
    }

    @action.bound
    subcribe(){
        this.count --;
    }

    @action.bound
    addLog(log:string){
        this.change_log.push(log);
    }
}
export const autoRunStore = new AutoRunStore();
autorun(() => {
    autoRunStore.addLog(`count 值改变为 ${autoRunStore.count}`);
})

class ReactionStore {
    @observable count:number = 0;
    @observable change_log:string[] = [];

    constructor(){
        makeObservable(this);
    }

    @action.bound
    increment(){
        this.count ++;
    }

    @action.bound
    subcribe(){
        this.count --;
    }

    @action.bound
    addLog(log:string){
        this.change_log.push(log);
    }

}
export const reactionStore = new ReactionStore();
reaction(() => reactionStore.count,() => {
    reactionStore.addLog(`count 值改为 ${reactionStore.count}}`);
})


class WhenStore {
    @observable count:number = 0;
    @observable change_log:string[] = [];

    constructor(){
        makeObservable(this);
    }

    @action.bound
    increment(){
        this.count++;
    }

    @action.bound
    subcribe(){
        this.count--;
    }

    @action.bound
    addLog(log:string){
        this.change_log.push(log);
    }
}
export const whenStore = new WhenStore();
when(() => !!(whenStore.count === 4),() => {
    whenStore.addLog(`count 值改为==== ${whenStore.count}`);
})

class UtilsStore {
    normal_num = 0;
    normal_set = new Set();
    normal_arr = [];
    normal_obj = {};
    normal_map = new Map();

    @observable num = 0;
    @observable set = new Set();
    @observable arr:number[] = [];
    @observable obj:object = {};
    @observable map = new Map();

    constructor(){
        makeObservable(this);
    }

    get arr_str(){
        return this.arr.join(",");
    }
}
export const utilsStore = new UtilsStore();

export class UserStore {
    @observable userInfo = {name:"张三",age:24};
    constructor(){
        makeObservable(this);
    }

    @action.bound
    setName(){
        this.userInfo.name = "李四";
    }
}

export const userStore = new UserStore();

export class TojsStore {
    @observable obj = {x:1};
    constructor(){
        makeObservable(this);
    }
}
export const toJsStore = new TojsStore();
export const primitiveValue = toJS(toJsStore.obj);

export class ConfigureStore {
    count = 0;
    constructor(){
        makeAutoObservable(this);
    }

    increment(){
        this.count++;
    }
}
export const configureStore = new ConfigureStore();

